Opensky

OpenSky provides api to get data for flights in progress. It is rate limited

Code
import requests
import pandas as pd
import geopandas
Code
def fetch_opensky_data():
    url = "https://opensky-network.org/api/states/all"
    response = requests.get(url)
    data = response.json()

    columns = [
        "icao24", "callsign", "origin_country", "time_position", "last_contact",
        "longitude", "latitude", "baro_altitude", "on_ground", "velocity",
        "heading", "vertical_rate", "sensors", "geo_altitude", "squawk",
        "spi", "position_source"
    ]

    df_raw = pd.DataFrame(data['states'], columns=columns)
    return (
        df_raw
        .assign(
            time_position=pd.to_datetime(df_raw["time_position"], unit="s"),
            last_contact=pd.to_datetime(df_raw["last_contact"], unit="s"),
        )
    )

df_flights = fetch_opensky_data()


df_flihts_non_nan = df_flights.dropna(subset=["longitude", "latitude"])
gdf = geopandas.GeoDataFrame(
    df_flihts_non_nan,
    geometry=geopandas.points_from_xy(df_flihts_non_nan.longitude, df_flihts_non_nan.latitude),
    crs="EPSG:4326",
)

gdf.explore(fullscreen=True, tooltip=False, popup=True)
Make this Notebook Trusted to load map: File -> Trust Notebook

Flights in world at notebook time

Number of flights by origin_country

Code
(
    df_flights
    .groupby("origin_country")
    .agg(num_flights=("icao24", "count"))
    .sort_values("num_flights", ascending=False)
    .head(20)
)
num_flights
origin_country
United States 1249
Australia 326
China 261
Germany 254
Ireland 242
Turkey 242
United Kingdom 234
India 221
Japan 188
France 185
Spain 163
Malta 154
Austria 147
Canada 129
Kingdom of the Netherlands 125
United Arab Emirates 116
Switzerland 93
Republic of Korea 86
Poland 86
Thailand 69

Top 20 countries with most flights

All flights

For reference

Code
df_flights
icao24 callsign origin_country time_position last_contact longitude latitude baro_altitude on_ground velocity heading vertical_rate sensors geo_altitude squawk spi position_source
0 39de4f TVF29UL France 2025-05-22 05:31:25 2025-05-22 05:31:26 4.8943 42.5502 11582.40 False 219.99 356.92 0.00 None 11742.42 1000 False 0
1 80162c AXB3030 India 2025-05-22 05:31:16 2025-05-22 05:31:22 55.6394 22.5508 11887.20 False 237.30 68.11 0.00 None 12702.54 5215 False 0
2 39de4b TVF32ER France 2025-05-22 05:31:26 2025-05-22 05:31:26 1.3234 47.2435 8534.40 False 198.85 15.76 0.00 None 8587.74 1000 False 0
3 39de4c TVF3423 France 2025-05-22 05:31:25 2025-05-22 05:31:25 16.8381 44.6504 11567.16 False 210.49 284.00 -0.33 None 11719.56 5316 False 0
4 407a38 NPT902 United Kingdom 2025-05-22 05:31:25 2025-05-22 05:31:25 -2.4088 49.5136 982.98 False 100.65 215.64 -7.48 None 1089.66 5140 False 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
5796 398570 AFR76BR France 2025-05-22 05:31:25 2025-05-22 05:31:25 3.5937 48.5984 3436.62 False 129.14 302.80 -3.90 None 3489.96 1000 False 0
5797 398571 AFR72EK France 2025-05-22 05:31:16 2025-05-22 05:31:21 9.1957 48.6884 NaN True 0.00 75.94 NaN None NaN None False 0
5798 398572 AFR12GR France 2025-05-22 05:31:25 2025-05-22 05:31:25 -0.6466 51.3755 8458.20 False 233.96 141.52 9.10 None 8542.02 6312 False 0
5799 a0c7b3 ABX3102 United States 2025-05-22 05:31:25 2025-05-22 05:31:26 -77.7661 41.9711 11285.22 False 254.46 73.80 0.00 None 11330.94 4043 False 0
5800 458666 VKG1512 Denmark 2025-05-22 05:31:26 2025-05-22 05:31:26 10.3125 59.0473 8999.22 False 238.90 186.93 5.85 None 8633.46 6005 False 0

5801 rows × 17 columns